package org.hiberlyzer.ui;

import java.awt.BorderLayout;
import java.util.Comparator;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Map.Entry;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;

import org.hiberlyzer.DataSource;
import org.hiberlyzer.Metadata;
import org.hiberlyzer.Property;

public class ObjectBrowser extends JPanel
{
	private JTree objectTree;
	private DataSource dataSource;
	
	public ObjectBrowser(DataSource dataSource)
	{
		super(new BorderLayout());
		this.dataSource = dataSource;
		populateTreeWithClassMetadata();
		JScrollPane scrollPane = new JScrollPane(objectTree);
		add(scrollPane, BorderLayout.CENTER);
	}

	private void populateTreeWithClassMetadata()
	{
		DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Entities");
		SortedMap<Class, Metadata> metadataMap = 
			new TreeMap<Class, Metadata>(new Comparator<Class>(){
				public int compare(Class o1, Class o2)
				{
					return o1.getSimpleName().compareToIgnoreCase(o2.getSimpleName());
				}});
		metadataMap.putAll(dataSource.getMetadataSource().getAllClassMetadata());
		buildAllEntityNodes(rootNode, metadataMap);
		objectTree = new JTree(rootNode);
	}

	private void removeNodeIfExists(DefaultMutableTreeNode entityNode, DefaultMutableTreeNode nodeToRemove)
	{
		for(int i = 0; i < entityNode.getChildCount(); i++)
		{
			DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) entityNode.getChildAt(i);
			if(childNode.getUserObject().equals(nodeToRemove.getUserObject()))
			{
				childNode.removeFromParent();
				return;
			}
		}
	}

	private void buildAllEntityNodes(DefaultMutableTreeNode rootNode, SortedMap<Class, Metadata> metadataMap)
	{
		for(Entry<Class, Metadata> mapEntry : metadataMap.entrySet())
		{
			String entityName = mapEntry.getKey().getSimpleName();
			Metadata meta = mapEntry.getValue();
			DefaultMutableTreeNode entityNode = buildNodeForEntity(entityName, meta);
			rootNode.add(entityNode);
		}
	}

	private DefaultMutableTreeNode buildNodeForEntity(String key, Metadata metadata)
	{
		DefaultMutableTreeNode entityNode = new DefaultMutableTreeNode(key);
		
		entityNode.add(new DefaultMutableTreeNode(metadata.getIdentifier().getName() + ": " + metadata.getIdentifier().getType()));
		for(Property property : getSortedProperties(metadata))
		{
			String nodeText = property.getName() + ": " + property.getType();
			DefaultMutableTreeNode propertyNode = new DefaultMutableTreeNode(nodeText);
			entityNode.add(propertyNode);
		}
		//TODO Subclasses in ObjectBrowser
//		for(Entry<Class, Metadata> subclassEntry : metadata.getSubclassMetadata().entrySet())
//		{
//			entityNode.add(buildNodeForEntity(subclassEntry.getKey().getSimpleName(), subclassEntry.getValue()));
//		}
		return entityNode;
	}
	
	private SortedSet<Property> getSortedProperties(Metadata metadata)
	{
		SortedSet<Property> properties = new TreeSet<Property>(new Comparator<Property>(){
			public int compare(Property prop1, Property prop2)
			{
				return prop1.getName().compareToIgnoreCase(prop2.getName());
			}});
		
		for(Property property : metadata.getProperties())
		{
			properties.add(property);
		}
		return properties;
	}
}
